package org.example.utils

import org.apache.commons.lang3.StringUtils
import org.example.common.Logging
import org.example.constant.ApolloConst
import redis.clients.jedis.Jedis

import java.sql._
import java.text.SimpleDateFormat
import java.util
import java.util.{Calendar, Date}
import scala.collection.mutable
import scala.collection.mutable.ListBuffer

/**
 * 搜索工具类
 */
object SearchInfo extends Logging {
 // private val RISK_RULE_SQL = "select a.id,a.risk_name,a.enable,b.warn_type_code,b.threshold,b.risk_level from hzcp_itms.base_risk_info a ,hzcp_itms.base_risk_detail_info b where a.id=b.risk_id"
  private val RISK_RULE_SQL = "select a.id,a.risk_name,a.enable,b.warn_type_code,b.threshold,b.risk_level from zcov.basic_risk_info a ,zcov.config_risk_detail_info b where a.id=b.risk_id"
  //车辆基础信息
  //private val VEHICLE_INFO_SQL = "select plate_num,plate_color from hdsp_itms.base_into_vehicle_info where status = 'NORMAL' and is_deleted != 1"
  private val VEHICLE_INFO_SQL = "select plate_num,plate_color from zcov.basic_vehicle_info where status = 1 and deleted != 1"
  //private val BASE_VEHICLE_INFO_SQL = "select plate_num,plate_color,use_nature,enterprise_code,control_type from hdsp_itms.base_into_vehicle_info where status = 'NORMAL' and is_deleted != 1"
  //private val BASE_VEHICLE_INFO_SQL = "select plate_num,plate_color,use_nature,enterprise_code,control_type from hdsp_itms.base_into_vehicle_info where status = 'NORMAL' and is_deleted != 1"
  //V2.3.1取消车辆管控类型，只关注二级使用性质，control_type字段存末级使用性质，如果不为null，则use_nature取末级性质
  private val BASE_VEHICLE_INFO_SQL =
    """
      |select
      | plate_num,
      | plate_color,
      | if(control_type != -1,control_type,use_nature) use_nature,
      | enterprise_code,
      | control_type
      |from
      | zcov.basic_vehicle_info
      |where status = 1 and deleted != 1
      |""".stripMargin
  //企业基础信息
  //private val BASE_ENTERPRISE_SQL = "select enterprise_code,enterprise_name from hdsp_itms.base_into_enterprise_info"
  private val BASE_ENTERPRISE_SQL = "select enterprise_code,enterprise_name from zcov.basic_enterprise_info"
  //驾驶员基础信息
  //private val BASE_DRIVER_SQL = "select license_number,enterprise_code,telephone from hdsp_itms.base_transport_driver"
  private val BASE_DRIVER_SQL = "select license_number,enterprise_code,telephone from zcov.basic_driver_info"
  //平台基础信息
  //private val BASE_PLATFORM_SQL = "select platform_code,platform_name from hdsp_itms.base_into_platform_info"
  private val BASE_PLATFORM_SQL = "select platform_code,platform_name from zcov.basic_into_platform_info"
  /**
   * 获取风险发生时间-5小时  生成主键用
   *
   * @return
   */
  def getRiskCodeTime(time: String): String = {
    var days = ""
    val fiveHourTime: Long = time.toLong - 5 * 60 * 60 * 1000 //5小时前时间
    val fiveHourT = new Date(fiveHourTime)

    val today = new Date(time.toLong) //当前时间

    val dateFormat: SimpleDateFormat = new SimpleDateFormat("dd")
    val fiveHourD = dateFormat.format(fiveHourT) //5小时前日期天
    val todayD = dateFormat.format(today) //当前时间天
    val dateFormat2: SimpleDateFormat = new SimpleDateFormat("yyyyMMdd")
    if (fiveHourD.equals(todayD)) {
      days = dateFormat2.format(today)
    } else {
      days = dateFormat2.format(time.toLong - 24 * 60 * 60 * 1000)
    }
    days
  }


  /**
   * 获取redis过期时间
   *
   * @return
   */
  def getSecondsNextEarlyMorning(): Long = {
    val cal: Calendar = Calendar.getInstance()
    val now: Long = System.currentTimeMillis()
    val dateFormat: SimpleDateFormat = new SimpleDateFormat("HH")
    val nowHour = dateFormat.format(new Date(now))
    if (nowHour.toInt < 5) {
      cal.add(Calendar.DAY_OF_YEAR, 0)
    } else {
      cal.add(Calendar.DAY_OF_YEAR, 1)
    }
    cal.set(Calendar.HOUR_OF_DAY, 5)
    cal.set(Calendar.SECOND, 0)
    cal.set(Calendar.MINUTE, 0)
    cal.set(Calendar.MILLISECOND, 0)
    val time: Long = (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000
    time
  }


  def getInfo(map: mutable.HashMap[String, String], infoName: String): String = {
    if (map.contains(infoName)) {
      map(infoName)
    } else {
      "-"
    }
  }


  def mysqlConn(): Connection = {
    val url = ApolloConst.jgdMysqlURL
    val username = ApolloConst.jgdMysqlUserName
    val password = ApolloConst.jgdMysqlPassWord
    var connection: Connection = null
    Class.forName("com.mysql.jdbc.Driver") //加载数据库驱动
    connection = DriverManager.getConnection(url, username, password)
    connection
  }

  /**
   * 获取报警编码
   *
   * @param bigType   kafka消息中的dataType
   * @param smallType kafka消息中的eventType
   * @return
   */
  def getWarnTypeCode(bigType: String, smallType: String): String = {
    val connection: Connection = mysqlConn()
    var warnTypeCode = ""
    try {
      val statement = connection.createStatement()
      val resultSet = statement.executeQuery("select warning_type_code from hzcp_itms.base_warning_type where warning_big_type= '" + bigType + "' and warning_small_type='" + smallType + "'")
      while (resultSet.next()) {
        warnTypeCode = resultSet.getString("warning_type_code")
      }
    } catch {
      case e => e.printStackTrace
    }
    connection.close()
    warnTypeCode
  }

  /**
   * 获取报警中文名称
   *
   * @param warnTypeCode 报警编码
   * @return
   */
  def warnTypeName(warnTypeCode: String): String = {
    val connection: Connection = mysqlConn()
    var warning_type_name = ""
    try {
      val statement = connection.createStatement()
      val resultSet = statement.executeQuery("select warning_type_name from zcov.base_warning_type where warning_type_code='" + warnTypeCode + "'")
      while (resultSet.next()) {
        warning_type_name = resultSet.getString("warning_type_name")
      }
    } catch {
      case e => e.printStackTrace
    }
    connection.close()
    warning_type_name
  }

  /**
   * 获取报警等级
   *
   * @param warnTypeCode 报警编码
   * @return
   */
  def getLevelId(warnTypeCode: String): String = {
    val connection: Connection = mysqlConn()
    var level_id = ""
    try {
      val statement = connection.createStatement()
      val resultSet = statement.executeQuery("select warning_level_id from zcov.base_warning_type where warning_type_code='" + warnTypeCode + "'")

      while (resultSet.next()) {
        level_id = resultSet.getString("warning_level_id")
      }
    } catch {
      case e => e.printStackTrace
    }
    connection.close()
    level_id
  }

  /**
   * 获取报警字典
   * @param bigType  kafka消息中的dataType
   * @param smallType kafka消息中的eventType
   * @return
   */
  def getBaseWarnByType(bigType:String, smallType:String):(String, String, String) = {
    val connection: Connection = mysqlConn()
    var warnTypeCode =""
    var warningTypeName =""
    var levelId =""
    try {
      val statement = connection.createStatement()
      val resultSet = statement.executeQuery("select warning_type_code,warning_type_name,warning_level_id from zcov.config_base_warning_type where warning_big_type= '"+bigType+"' and warning_small_type='"+smallType+"'")
      while (resultSet.next()) {
        warnTypeCode = resultSet.getString("warning_type_code")
        warningTypeName = resultSet.getString("warning_type_name")
        levelId = resultSet.getString("warning_level_id")
      }
    } catch {
      case e => e.printStackTrace
    }
    connection.close()
    (warnTypeCode, warningTypeName, levelId)
  }

  /**
   * 获取企业编号以及下属车辆数
   * @return
   */
  def getEnterpriseCode():ListBuffer[(String,Int)]={
    val connection: Connection = mysqlConn()
    val enterpriseList = new ListBuffer[(String, Int)]
    try {
      val statement = connection.createStatement()
      val resultSet = statement.executeQuery("select enterprise_code,count(*) as total from zcov.basic_vehicle_info where status = 1 and deleted != 1 group by enterprise_code")
      while (resultSet.next()) {
        val enterpriseCode = resultSet.getString("enterprise_code")
        val sum = resultSet.getString("total").toInt
        enterpriseList+=((enterpriseCode,sum))
      }
    } catch {
      case e => e.printStackTrace
    }
    connection.close()
    enterpriseList
  }
  /**
   * 获取企业编号以及下属车辆数
   * @return
   */
  def getUseNature(vehicle:String,vehicleColor:String):String={
    val connection: Connection = mysqlConn()
    val enterpriseList = new ListBuffer[(String, Int)]
    var useNature = "无"
    try {
      val statement = connection.createStatement()
      val resultSet = statement.executeQuery("select use_nature from zcov.basic_vehicle_info where plate_num = '"+vehicle+"' and plate_color='"+vehicleColor+"'")
      while (resultSet.next()) {
        useNature = resultSet.getString("use_nature")
      }
    } catch {
      case e => e.printStackTrace
    }
    connection.close()
    useNature
  }
  /**
   * 获取企业编号以及下属车辆数
   * @return
   */
  def getEnterpriseMap():util.HashMap[String,String]={
    val connection: Connection = mysqlConn()
    val map = new util.HashMap[String,String]()
    try {
      val statement = connection.createStatement()
      val resultSet = statement.executeQuery("select plate_num,plate_color,enterprise_code from zcov.basic_vehicle_info where status = 1 and deleted != 1")
      while (resultSet.next()) {
        val vehicleNo = resultSet.getString("plate_num")
        val vehicleColor = resultSet.getString("plate_color")
        val enterpriseCode = resultSet.getString("enterprise_code")
        val primaryKey = vehicleNo +"#"+vehicleColor
        map.put(primaryKey,enterpriseCode)
      }
    } catch {
      case e => e.printStackTrace
    }
    connection.close()
    map
  }
  /**
   * 获取报警字典信息
   *
   * @return
   */
  def getBaseWarnInfo(): mutable.HashMap[String, (String, String)] = {
    val connection: Connection = mysqlConn()
    val result = new mutable.HashMap[String, (String, String)]()
    try {
      val statement = connection.createStatement()
      val resultSet = statement.executeQuery("select warning_type_code,warning_type_name,warning_level_id from zcov.base_warning_type")
      while (resultSet.next()) {
        val warnTypeCode = resultSet.getString("warning_type_code")
        val warningTypeName = resultSet.getString("warning_type_name")
        val levelId = resultSet.getString("warning_level_id")
        result += ((warnTypeCode, (warningTypeName, levelId)))
      }
    } catch {
      case e => e.printStackTrace
    }
    connection.close()
    result
  }


  /**
   * 获取风险配置
   *
   * @return
   */
  def getRiskRule(): mutable.HashMap[String, mutable.HashMap[String, mutable.Set[mutable.HashMap[String, String]]]] = {
    val connection: Connection = mysqlConn()
    var riskRule: mutable.HashMap[String, mutable.HashMap[String, mutable.Set[mutable.HashMap[String, String]]]] = mutable.HashMap[String, mutable.HashMap[String, mutable.Set[mutable.HashMap[String, String]]]]()
    try {
      val statement = connection.createStatement()
      val resultSet = statement.executeQuery(RISK_RULE_SQL)
      while (resultSet.next()) {
        val enable = resultSet.getString("enable")

        if (enable != null && enable.equals("NORMAL")) {
          val riskName = resultSet.getString("risk_name")
          val warnTypeCode = resultSet.getString("warn_type_code")
          val threshold = resultSet.getString("threshold")
          val riskTypeCode = resultSet.getString("id")
          val riskGradeCode = resultSet.getString("risk_level")
          val riskDescription = warnTypeName(warnTypeCode)
          if (riskRule.contains(riskName)) {
            var levelInfo: mutable.HashMap[String, mutable.Set[mutable.HashMap[String, String]]] = riskRule(riskName)
            if (levelInfo.contains(riskGradeCode)) {
              var riskInfo: mutable.Set[mutable.HashMap[String, String]] = levelInfo(riskGradeCode)
              var warnRule: mutable.HashMap[String, String] = mutable.HashMap[String, String]()
              warnRule += (("warnTypeCode" -> warnTypeCode))
              warnRule += (("threshold" -> threshold))
              warnRule += (("warnTypeCode" -> warnTypeCode))
              warnRule += (("riskDescription" -> riskDescription))
              warnRule += (("riskTypeCode" -> riskTypeCode))
              riskInfo += warnRule
            } else {
              val riskInfo = mutable.Set[mutable.HashMap[String, String]]()
              val warnRule: mutable.HashMap[String, String] = mutable.HashMap[String, String]()
              warnRule += (("warnTypeCode" -> warnTypeCode))
              warnRule += (("threshold" -> threshold))
              warnRule += (("warnTypeCode" -> warnTypeCode))
              warnRule += (("riskDescription" -> riskDescription))
              warnRule += (("riskTypeCode" -> riskTypeCode))
              riskInfo += warnRule
              levelInfo += ((riskGradeCode -> riskInfo))
            }
          } else {
            var levelInfo = mutable.HashMap[String, mutable.Set[mutable.HashMap[String, String]]]()
            val riskInfo = mutable.Set[mutable.HashMap[String, String]]()
            val warnRule: mutable.HashMap[String, String] = mutable.HashMap[String, String]()
            warnRule += (("warnTypeCode" -> warnTypeCode))
            warnRule += (("threshold" -> threshold))
            warnRule += (("warnTypeCode" -> warnTypeCode))
            warnRule += (("riskDescription" -> riskDescription))
            warnRule += (("riskTypeCode" -> riskTypeCode))
            riskInfo += warnRule
            levelInfo += ((riskGradeCode -> riskInfo))
            riskRule += ((riskName -> levelInfo))
          }
        }
      }
    } catch {
      case e => e.printStackTrace
    }
    connection.close()
    riskRule
  }

  /**
   * 获取需要监控的车辆信息
   *
   * @return
   */
  def getVehicleNos(): ListBuffer[(String, String)] = {
    val list = new ListBuffer[(String, String)]()
    var connection: Connection = null
    var statement: Statement = null
    var resultSet: ResultSet = null

    try {
      connection = mysqlConn()
      statement = connection.createStatement()
      resultSet = statement.executeQuery(VEHICLE_INFO_SQL)
      while (resultSet.next()) {
        list += ((resultSet.getString("plate_num"), resultSet.getString("plate_color")))
      }
    } catch {
      case e => e.printStackTrace
    } finally {

      try {
        CommonUtils.autoCloseable(resultSet, statement, connection)
      } catch {
        case e => logger.error("关闭获取需要监控的车辆信息的连接失败！")
      }
    }
    list
  }

  /**
   * 更新redis的基本信息
   *
   * @param redis
   */
  def updateBaseInfo(redis: Jedis): Unit = {
    var connection: Connection = null
    var statement: Statement = null
    var resultSet: ResultSet = null
    var statement1: Statement = null
    var resultSet1: ResultSet = null
    var statement2: Statement = null
    var resultSet2: ResultSet = null
    var statement3: Statement = null
    var resultSet3: ResultSet = null
    try {
      connection = mysqlConn()
      // 更新企业基本信息
      statement = connection.createStatement()
      resultSet = statement.executeQuery(BASE_ENTERPRISE_SQL)
      val resultMap = new util.HashMap[String, String]()
      while (resultSet.next()) {
        val enterpriseCode = resultSet.getString("enterprise_code")
        val enterpriseName = resultSet.getString("enterprise_name")
        resultMap.put(enterpriseCode, enterpriseName)
      }
      if (!resultMap.isEmpty) {
        redis.hmset("enterprise", resultMap)
      }
      // 更新车辆基本信息
      statement1 = connection.createStatement()
      resultSet1 = statement1.executeQuery(BASE_VEHICLE_INFO_SQL)
      while (resultSet1.next()) {
        val vehicleNo = resultSet1.getString("plate_num")
        val vehicleColor = resultSet1.getString("plate_color")
        val useNature = resultSet1.getString("use_nature")
        val enterpriseCode = resultSet1.getString("enterprise_code")
        //车辆管控类型
        val controlType = resultSet1.getString("control_type")
        if (!vehicleNo.isEmpty && !vehicleColor.isEmpty) {
          val primaryKey = vehicleNo + "#" + vehicleColor
          if (StringUtils.isNotEmpty(useNature)) {
            redis.hset("driverInfo:" + primaryKey, "useNature", useNature)
          }
          if (StringUtils.isNotEmpty(enterpriseCode)) {
            redis.hset("driverInfo:" + primaryKey, "vehicleEnterprise", enterpriseCode)
          }
          if (StringUtils.isNotEmpty(controlType)) {
            redis.hset("driverInfo:" + primaryKey, "controlType", controlType)
          }
        }
      }

      // 更新驾驶员基本信息
      statement2 = connection.createStatement()
      resultSet2 = statement2.executeQuery(BASE_DRIVER_SQL)
      while (resultSet2.next()) {
        val licenseNumber = resultSet2.getString("license_number")
        val driverEnterprise = resultSet2.getString("enterprise_code")
        var telephone = resultSet2.getString("telephone")
        if (StringUtils.isNotEmpty(licenseNumber)) {

          if (StringUtils.isNotEmpty(driverEnterprise)) {
            redis.hset("licenseNumber:" + licenseNumber, "driverEnterprise", driverEnterprise)
          }
          if (StringUtils.isEmpty(telephone)) {
            telephone = "-"
          }
          redis.hset("licenseNumber:" + licenseNumber, "telephone", telephone)

        }
      }
      // 更新平台基本信息
      statement3 = connection.createStatement()
      resultSet3 = statement3.executeQuery(BASE_PLATFORM_SQL)
      val resultMap3 = new util.HashMap[String, String]()
      while (resultSet3.next()) {
        val platformCode = resultSet3.getString("platform_code")
        val platformName = resultSet3.getString("platform_name")
        if (StringUtils.isNotEmpty(platformCode) && StringUtils.isNotEmpty(platformName)) {
          resultMap3.put(platformCode, platformName)
        }
      }
      redis.hmset("platform", resultMap3)
    } catch {
      case e => logger.error("更新基本信息异常！")
    } finally {
      try {
        CommonUtils.autoCloseable(resultSet, resultSet1, resultSet2, resultSet3, statement, statement1, statement2, statement3, connection)
      } catch {
        case e => logger.error("关闭基本信息更新的连接失败！")
      }
    }

  }

  /**
   * 更新隐患redis的基本信息
   *
   * @param redis
   */
  def updateBaseInfoForHidden(redis: Jedis): Unit = {
    var connection: Connection = null
    var statement: Statement = null
    var resultSet: ResultSet = null
    var statement1: Statement = null
    var resultSet1: ResultSet = null
    var statement2: Statement = null
    var resultSet2: ResultSet = null
    var statement3: Statement = null
    var resultSet3: ResultSet = null
    try {
      connection = mysqlConn()
      // 更新企业基本信息
      statement = connection.createStatement()
      resultSet = statement.executeQuery(BASE_ENTERPRISE_SQL)
      val resultMap = new util.HashMap[String, String]()
      while (resultSet.next()) {
        val enterpriseCode = resultSet.getString("enterprise_code")
        val enterpriseName = resultSet.getString("enterprise_name")
        resultMap.put(enterpriseCode, enterpriseName)
      }
      if (!resultMap.isEmpty) {
        redis.hmset("hiddenEnterprise", resultMap)
      }
      // 更新车辆基本信息
      statement1 = connection.createStatement()
      resultSet1 = statement1.executeQuery(BASE_VEHICLE_INFO_SQL)
      while (resultSet1.next()) {
        val vehicleNo = resultSet1.getString("plate_num")
        val vehicleColor = resultSet1.getString("plate_color")
        val useNature = resultSet1.getString("use_nature")
        val enterpriseCode = resultSet1.getString("enterprise_code")
        //车辆管控类型
        val controlType = resultSet1.getString("control_type")
        if (!vehicleNo.isEmpty && !vehicleColor.isEmpty) {
          val primaryKey = vehicleNo + "#" + vehicleColor
          if (StringUtils.isNotEmpty(useNature)) {
            redis.hset("hiddenDriverInfo:" + primaryKey, "useNature", useNature)
          }
          if (StringUtils.isNotEmpty(enterpriseCode)) {
            redis.hset("hiddenDriverInfo:" + primaryKey, "vehicleEnterprise", enterpriseCode)
          }
          if (StringUtils.isNotEmpty(controlType)) {
            redis.hset("hiddenDriverInfo:" + primaryKey, "controlType", controlType)
          }
        }
      }

      // 更新驾驶员基本信息
      statement2 = connection.createStatement()
      resultSet2 = statement2.executeQuery(BASE_DRIVER_SQL)
      while (resultSet2.next()) {
        val licenseNumber = resultSet2.getString("license_number")
        val driverEnterprise = resultSet2.getString("enterprise_code")
        var telephone = resultSet2.getString("telephone")
        if (StringUtils.isNotEmpty(licenseNumber)) {

          if (StringUtils.isNotEmpty(driverEnterprise)) {
            redis.hset("hiddenLicenseNumber:" + licenseNumber, "driverEnterprise", driverEnterprise)
          }
          if (StringUtils.isEmpty(telephone)) {
            telephone = "-"
          }
          redis.hset("hiddenLicenseNumber:" + licenseNumber, "telephone", telephone)

        }
      }
      // 更新平台基本信息
      statement3 = connection.createStatement()
      resultSet3 = statement3.executeQuery(BASE_PLATFORM_SQL)
      val resultMap3 = new util.HashMap[String, String]()
      while (resultSet3.next()) {
        val platformCode = resultSet3.getString("platform_code")
        val platformName = resultSet3.getString("platform_name")
        if (StringUtils.isNotEmpty(platformCode) && StringUtils.isNotEmpty(platformName)) {
          resultMap3.put(platformCode, platformName)
        }
      }
      redis.hmset("hiddenPlatform", resultMap3)
    } catch {
      case e => logger.error("更新基本信息异常！")
    } finally {
      try {
        CommonUtils.autoCloseable(resultSet, resultSet1, resultSet2, resultSet3, statement, statement1, statement2, statement3, connection)
      } catch {
        case e => logger.error("关闭基本信息更新的连接失败！")
      }
    }

  }

  /**
   * 根据车牌号和车牌颜色获取所属公司
   *
   * @return
   */
  def getenterpriseByPlate(plateNum: String, plateColor: String): (String, String) = {
    val list = new ListBuffer[(String, String)]()
    var connection: Connection = null
    var statement: PreparedStatement = null
    var resultSet: ResultSet = null
    var result = ("", "")
    try {
      connection = mysqlConn()
      val sql = "select a.enterprise_code,a.use_nature from zcov.basic_vehicle_info a where a.plate_num = ? and a.plate_color = ? and a.status = 1 and a.deleted != 1"
      statement = connection.prepareStatement(sql)
      statement.setString(1, plateNum)
      statement.setString(2, plateColor)
      resultSet = statement.executeQuery()
      while (resultSet.next()) {
        result = (resultSet.getString("enterprise_code"), resultSet.getString("use_nature"))
      }
    } catch {
      case e => e.printStackTrace
    } finally {

      try {
        CommonUtils.autoCloseable(resultSet, statement, connection)
      } catch {
        case e => logger.error("关闭获取需要监控的车辆信息的连接失败！")
      }
    }

    result
  }

}
